home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / CPPTASK.ARJ / TSKDOS.ASM < prev    next >
Assembly Source File  |  1991-07-26  |  20KB  |  973 lines

  1. ;
  2. ;    CTask - DOS access module.
  3. ;
  4. ;    Public Domain Software written by
  5. ;        Thomas Wagner
  6. ;        Patschkauer Weg 31
  7. ;        D-1000 Berlin 33
  8. ;        West Germany
  9. ;
  10. ;
  11. ; The DOS interrupt (and the related direct disk I/O interrupts) are
  12. ; not reentrant. Access to DOS thus has to be channelled such that no
  13. ; two tasks use DOS services simultaneously. However, there is one
  14. ; exception to this rule. Whenever DOS is waiting for the keyboard, it
  15. ; issues a special interrupt, INT 28h, to signal that background
  16. ; processing for functions > 0Ch may be performed. This is used in the
  17. ; DOS interface for CTask in the following manner:
  18. ;
  19. ;   A task issuing a DOS interrupt will request one of two resources:
  20. ;   "lower_dos" for functions <= 0C, "upper_dos" for functions > 0C.
  21. ;   If a task gets access to "lower_dos", it will also request the
  22. ;   "upper_dos" resource to lock out other tasks from interrupting.
  23. ;   This "upper_dos" resource is shortly released on each INT 28, and
  24. ;   then immediately reclaimed, with task priority temporarily raised
  25. ;   to the maximum value. The first task waiting to execute a 
  26. ;   function > 0C will thus be scheduled to execute the request, but
  27. ;   the resource will be reassigned to the INT 28 handler as soon as
  28. ;   this request terminates, so the waiting task will not be delayed too
  29. ;   long.
  30. ;
  31. ; There are two additional safety measures which have to be taken to
  32. ; avoid getting into conflicts with other resident background programs,
  33. ; especially the DOS PRINT background spooler:
  34. ;
  35. ;   Before requesting any resource, the status of the DOS critical section
  36. ;   flag is checked. If this flag is set, the task is made waiting for
  37. ;   the flag to be cleared.
  38. ;   Only the task that set the flag will be allowed access to DOS.
  39. ;
  40. ;   Before actually executing the request, the status of the DOS in-use
  41. ;   flag is checked. If this flag is set, the task enters a busy waiting
  42. ;   loop, calling the scheduler so that the processor is not tied up.
  43. ;
  44. ; NOTE: The method for checking the status of DOS is described in-depth
  45. ;    in the book "The MS-DOS Encyclopedia" from Microsoft Press, in
  46. ;    the chapter on TSR programming. The logic in this module was
  47. ;    developed without the help of this book, so if you compare
  48. ;    the code here with the routines in the Encyclopedia, you may
  49. ;    notice that not all re-entry conditions are checked here.
  50. ;    According to my experience with debugging TSR's and CTask, the
  51. ;    logic should be sufficient for all but the most obscure TSR's.
  52. ;    If you want to be completely on the safe side, you might consider
  53. ;    adding the more thorough checks listed in the Encyclopedia.
  54. ;
  55. ;
  56.     name    tskdos
  57. ;
  58.     .model    large
  59. ;
  60.     public    _tsk_install_dos
  61.     public    _tsk_remove_dos
  62. ;
  63. ;
  64.     include    tsk.mac
  65. ;
  66. CSECT        =    2ah    ; Critical Section Interrupt
  67. get_in_use_flag    =    34h    ; DOS-function to get in_use_flag address
  68. ;
  69. ;
  70. intseg    segment at 0
  71.         org    20h*4
  72. termoff        dw    ?    ; program terminate vector
  73. termseg        dw    ?
  74.         org    21h*4
  75. idosoff        dw    ?    ; dos interrupt
  76. idosseg        dw    ?
  77.         org    25h*4
  78. absreadoff    dw    ?    ; absolute disk read
  79. absreadseg    dw    ?
  80.         org    26h*4
  81. abswriteoff    dw    ?    ; absolute disk write
  82. abswriteseg    dw    ?
  83.         org    27h*4
  84. keepoff        dw    ?    ; Terminate but stay resident
  85. keepseg        dw    ?
  86.         org    28h*4
  87. idleoff        dw    ?    ; dos idle interrupt
  88. idleseg        dw    ?
  89.         org    CSECT*4
  90. csectoff    dw    ?    ; dos critical section
  91. csectseg    dw    ?
  92. ;
  93. intseg    ends
  94. ;
  95. ;----------------------------------------------------------------------------
  96. ;
  97. ;       externally defined variables
  98. ;
  99.         extrn   _tsk_current: dword
  100.         extrn   _lower_dos: resource
  101.         extrn   _upper_dos: resource
  102.         extrn   _critical: flag
  103. ;
  104. ;       externally defined functions
  105. ;
  106.         extrn   _asm_request_resource: far
  107.         extrn   _asm_release_resource: far
  108.         extrn   _asm_set_flag: far
  109.         extrn   _asm_clear_flag: far
  110.         extrn   _asm_wait_flag_clear: far
  111.         extrn   _asm_remove_tasker: far
  112.         extrn   scheduler: far
  113. ;
  114.     .data
  115. ;
  116. ;
  117. term_err_msg    db    0dh,0ah,"Program terminated - CTask uninstalled"
  118.         db    0dh,0ah,'$'
  119. ;
  120. idle_active    db    0            ; Idle-Interrupt active
  121. dos310        db    0        ; DOS version >= 3.10
  122. ;
  123. ;
  124.     .data?
  125. ;
  126. in_use        dd    ?        ; Adress of DOS in-use-flag
  127. in_error    dd    ?        ; Adress of DOS error-mode-flag
  128. ;
  129. ;
  130. idle_ss        dw    ?        ; Stack save
  131. idle_sp        dw    ?
  132. ;
  133.         dw    256 dup(?)    ; Stack for IDLE-Interrupt
  134. local_stack    label    word
  135. ;
  136.     .code
  137. ;
  138. ;    Original Interrupt-Entries
  139. ;
  140. savtermoff    dw    ?        ; Terminate vector save
  141. savtermseg    dw    ?
  142. ;
  143. savdos        label    dword        ; original DOS-Entry
  144. savdosoff    dw    ?
  145. savdosseg    dw    ?
  146. ;
  147. savidle        label    dword        ; original IDLE-Entry
  148. savidleoff    dw    ?
  149. savidleseg    dw    ?
  150. ;
  151. savcsect    label    dword        ; Critical Section save
  152. savcsectoff    dw    ?
  153. savcsectseg    dw    ?
  154. ;
  155. savabsread    label    dword        ; Absolute Disk Read save
  156. savabsreadoff    dw    ?
  157. savabsreadseg    dw    ?
  158. ;
  159. savabswrite    label    dword        ; Absolute Disk Write save
  160. savabswriteoff    dw    ?
  161. savabswriteseg    dw    ?
  162. ;
  163. savkeepoff    dw    ?        ; Terminate resident vector save
  164. savkeepseg    dw    ?
  165. ;
  166. critsect_active    db    0        ; DOS Critical Section active
  167. ctask_active    db    0        ; CTask DOS call active
  168. crit_task    dd    ?        ; Task requesting critical section
  169. ;
  170. ;
  171. dos    macro
  172.     pushf
  173.     cli
  174.     call    cs:savdos
  175.     endm
  176. ;
  177. ;---------------------------------------------------------------------------
  178. ;
  179.     .code
  180. ;
  181. ;
  182. ;    void tsk_install_dos (void)
  183. ;
  184. ;        Install DOS handler
  185. ;
  186. ;       Invoked by tasker_class::tasker_class
  187. ;
  188. _tsk_install_dos    proc
  189. ;
  190. ;
  191. ;    Get the address of DOS's in_use-flag. This flag indicates that
  192. ;    DOS is already active. This might happen if there are other
  193. ;    background tasks, like popups or print spoolers, active in
  194. ;    parallel to CTask.
  195. ;    This is also the address of the critical error flag in DOS. Beginning 
  196. ;    with DOS 3.10 the flag is located one byte before the in_use_flag.
  197. ;    With older DOS versions, we would have to search through DOS for the 
  198. ;    address. This is omitted here, but you could include the code
  199. ;    for pre 3.1 versions from pages 378-379 of the MS-DOS Encyclopedia.
  200. ;    
  201.     mov    ah,get_in_use_flag
  202.     int    21h
  203.     mov    word ptr in_use,bx
  204.     mov    word ptr in_use+2,es
  205.     mov    word ptr in_error+2,es
  206. ;
  207.     push    bx
  208.     mov    ah,30h
  209.     int    21h
  210.     pop    bx
  211.     cmp    al,3
  212.     jb    not_dos3
  213.     cmp    al,0ah
  214.     je    not_dos3    ; OS/2 compatibility box
  215.     cmp    ah,10
  216.     jb    not_dos3
  217.     inc    dos310
  218.     dec    bx
  219.     mov    word ptr in_error,bx
  220.     jmp    short save_ints
  221. ;
  222. not_dos3:
  223.  
  224. ;
  225. ;    Save old interrupt vectors
  226. ;
  227. save_ints:
  228.         push    es
  229.     xor    ax,ax
  230.     mov    es,ax
  231. ;
  232.         assume  es:intseg
  233. ;
  234.     mov    ax,termoff        ; DOS
  235.     mov    savtermoff,ax
  236.     mov    ax,termseg
  237.     mov    savtermseg,ax
  238. ;
  239.     mov    ax,idosoff        ; DOS
  240.     mov    savdosoff,ax
  241.     mov    ax,idosseg
  242.     mov    savdosseg,ax
  243. ;
  244.     mov    ax,idleoff        ; IDLE
  245.     mov    savidleoff,ax
  246.     mov    ax,idleseg
  247.     mov    savidleseg,ax
  248. ;
  249.     mov    ax,csectoff        ; Critical Section
  250.     mov    savcsectoff,ax
  251.     mov    ax,csectseg
  252.     mov    savcsectseg,ax
  253. ;
  254.     mov    ax,absreadoff        ; Absolute Disk read
  255.     mov    savabsreadoff,ax
  256.     mov    ax,absreadseg
  257.     mov    savabsreadseg,ax
  258. ;
  259.     mov    ax,abswriteoff        ; Absolute Disk write
  260.     mov    savabswriteoff,ax
  261.     mov    ax,abswriteseg
  262.     mov    savabswriteseg,ax
  263. ;
  264.     mov    ax,keepoff        ; Terminate Resident
  265.     mov    savkeepoff,ax
  266.     mov    ax,keepseg
  267.     mov    savkeepseg,ax
  268. ;
  269. ;    Enter new Interrupt-Entries
  270. ;
  271.     cli
  272.     mov    idosoff,offset dosentry        ; DOS-Entry
  273.     mov    idosseg,cs
  274.     mov    idleoff,offset idleentry    ; Idle-Entry
  275.     mov    idleseg,cs
  276.     mov    termoff,offset terminate_int    ; Terminate Process Entry
  277.     mov    termseg,cs
  278.     mov    csectoff,offset critsectint    ; Critical Section Entry
  279.     mov    csectseg,cs
  280.     mov    keepoff,offset keep_int        ; Keep Process Entry
  281.     mov    keepseg,cs
  282.     mov    absreadoff,offset absread_int    ; Absolute Disk Read Entry
  283.     mov    absreadseg,cs
  284.     mov    abswriteoff,offset abswrite_int    ; Absolute Disk Write Entry
  285.     mov    abswriteseg,cs
  286.     sti
  287.         pop     es
  288. ;
  289.     ret
  290. ;
  291.     assume    es:nothing
  292. ;
  293. _tsk_install_dos    endp
  294. ;
  295. ;
  296. ;    void tsk_remove_dos (void)
  297. ;
  298. ;       Un-install DOS handler
  299. ;
  300. _tsk_remove_dos    proc
  301. ;
  302. ;    Delete resources & flags
  303. ;
  304.         push    es
  305.     xor    ax,ax
  306.     mov    es,ax
  307. ;
  308.         assume  es:intseg
  309. ;
  310. ;    Restore interrupt entries
  311. ;
  312.     cli
  313.     mov    ax,savtermoff
  314.     mov    termoff,ax
  315.     mov    ax,savtermseg
  316.     mov    termseg,ax
  317. ;
  318.     mov    ax,savdosoff
  319.     mov    idosoff,ax
  320.     mov    ax,savdosseg
  321.     mov    idosseg,ax
  322. ;
  323.     mov    ax,savidleoff
  324.     mov    idleoff,ax
  325.     mov    ax,savidleseg
  326.     mov    idleseg,ax
  327. ;
  328.     mov    ax,savcsectoff
  329.     mov    csectoff,ax
  330.     mov    ax,savcsectseg
  331.     mov    csectseg,ax
  332. ;
  333.     mov    ax,savabsreadoff
  334.     mov    absreadoff,ax
  335.     mov    ax,savabsreadseg
  336.     mov    absreadseg,ax
  337. ;
  338.     mov    ax,savabswriteoff
  339.     mov    abswriteoff,ax
  340.     mov    ax,savabswriteseg
  341.     mov    abswriteseg,ax
  342. ;
  343.     mov    ax,savkeepoff
  344.     mov    keepoff,ax
  345.     mov    ax,savkeepseg
  346.     mov    keepseg,ax
  347. ;
  348.     sti
  349. ;
  350.         pop     es
  351.     ret
  352. ;
  353.     assume    es:nothing
  354. ;
  355. _tsk_remove_dos    endp
  356. ;
  357. ;
  358. ;---------------------------------------------------------------------------
  359. ;
  360. ;    Stack-Offsets relative to BP
  361. ;
  362. caller_cs    =    4        ; Caller's CS
  363. caller_flags    =    6        ; Caller's Flags
  364. ;
  365. ;
  366. ;---------------------------------------------------------------------------
  367. ;
  368. ;    INT 25: Absolute Disk Read 
  369. ;
  370. ;    This interrupt is translated into INT 21, function C0.
  371. ;    This function is re-translated later after the necessary resources
  372. ;    have been requested.
  373. ;
  374. absread_int:
  375.     mov    ah,0c0h
  376.     jmp    short absrw_int
  377. ;
  378. ;
  379. ;---------------------------------------------------------------------------
  380. ;
  381. ;    INT 26: Absolute Disk Write
  382. ;
  383. ;    This interrupt is translated into INT 21, function C1.
  384. ;    This function is re-translated later after the necessary resources
  385. ;    have been requested.
  386. ;
  387. abswrite_int:
  388.     mov    ah,0c1h
  389. ;
  390. ;    Interrupts 25 und 26 leave the flag-word on the stack.
  391. ;    Since flags are removed in normal processing, the flag-word
  392. ;    has to be duplicated on the stack here.
  393. ;
  394. absrw_int:
  395.     push    bp            ; reserve space
  396.     push    bp            ; save BP
  397.     mov    bp,sp
  398.     sti
  399.     push    ax
  400.     mov    ax,4[bp]        ; Move return offset, segment down
  401.     mov    2[bp],ax
  402.     mov    ax,6[bp]
  403.     mov    4[bp],ax
  404.     mov    ax,8[bp]        ; duplicate flags
  405.     mov    6[bp],ax
  406.     pop    ax
  407.     push    caller_flags[bp]
  408.     jmp    short dosentry_2
  409. ;
  410. ;---------------------------------------------------------------------------
  411. ;
  412. ;    INT 27: Terminate But Stay Resident Interrupt
  413. ;
  414. ;    This interrupt is translated to INT 21, function 31.
  415. ;
  416. keep_int:
  417.     push    bp
  418.     mov    bp,sp
  419.     push    caller_flags[bp]    ; flags (bp-2)
  420.     sti                ; allow interrupts
  421. ;
  422.     add    dx,0fh            ; last addr + 0f to round
  423.     sub    dx,caller_cs[bp]    ; minus CS (= PSP)
  424.     mov    cl,4
  425.     shr    dx,cl            ; div 16 = paragraphs
  426.  
  427.     mov    ax,3100h        ; Keep process
  428.     jmp    short dosentry_2
  429. ;
  430. ;---------------------------------------------------------------------------
  431. ;
  432. ;    INT 20: Terminate Program interrupt
  433. ;
  434. ;    This interrupt is translated to INT 21, function 0.
  435. ;
  436. terminate_int:
  437.     mov    ah,0
  438. ;
  439. ;    fall through
  440. ;
  441. ;---------------------------------------------------------------------------
  442. ;
  443. ;    INT 21: DOS-Interrupt
  444. ;
  445. dosentry        proc    far
  446. ;
  447. ;    Save registers
  448. ;
  449.     push    bp
  450.     mov    bp,sp
  451.     push    caller_flags[bp]    ; flags (bp-2)
  452. ;
  453. dosentry_2:
  454.     push    es
  455.     push    ds
  456.     push    dx
  457.     push    cx
  458.     push    bx
  459.     push    ax
  460.     push    si
  461.     push    di
  462.     cld
  463.     mov    bx,SEG dgroup
  464.     mov    ds,bx
  465.     mov    es,bx
  466. ;
  467. ;
  468. ;    Here we check if the DOS critical region is active.
  469. ;    If yes, this means that some outside background process has
  470. ;    started DOS (most likely DOS PRINT).
  471. ;    To avoid busy waiting, we wait for the "critical" flag to be
  472. ;    cleared, if this is *not* the task that set the flag.
  473. ;    The task that set the critical task is *not* made waiting.
  474. ;
  475. wait_crit_loop:
  476.     cli
  477.     cmp    cs:critsect_active,0
  478.     je    no_crit
  479.     mov    ax,word ptr cs:crit_task
  480.     cmp    word ptr _tsk_current,ax
  481.     jne    wait_crit
  482.     mov    ax,word ptr cs:crit_task+2
  483.     cmp    word ptr _tsk_current+2,ax
  484.     je    no_crit
  485. ;
  486. wait_crit:
  487.     xor    ax,ax
  488.     push    ax
  489.     push    ax
  490.         mov     ax,offset _critical
  491.     push    ds
  492.     push    ax
  493.         call    _asm_wait_flag_clear
  494.     add    sp,8
  495. ;
  496. no_crit:
  497.     mov    cs:ctask_active,1    ; mark that we are active
  498.     sti                ; Interrupts allowed now
  499. ;
  500.         cmp     ah,4ch                  ; terminate?
  501.         jne     dosent_x
  502.         mov     ah,0                    ; translate to fn 0
  503. dosent_x:
  504.     cmp    ah,0ch
  505.     jbe    lower_funcs
  506.     jmp    upper_funcs
  507. ;
  508. ;    Functions 00-0C
  509. ;
  510. lower_funcs:
  511. ;
  512. ;    first, request the "lower_dos" resource
  513. ;
  514.         mov     bx,offset _lower_dos
  515.     xor    cx,cx
  516.     push    cx        ; no timeout
  517.     push    cx
  518.     push    ds        ; resource address
  519.     push    bx
  520.         call    _asm_request_resource
  521.     add    sp,8
  522. ;
  523. ;    we have it, now let's get the upper_dos resource, too
  524. ;
  525.         mov     bx,offset _upper_dos
  526.     xor    cx,cx
  527.     push    cx        ; no timeout
  528.     push    cx
  529.     push    ds        ; resource address
  530.     push    bx
  531.         call    _asm_request_resource
  532.     add    sp,8
  533. ;
  534. ;    both resources gained, now we may execute the function if dos is free
  535. ;
  536.     pop    di
  537.     pop    si
  538.     pop    ax
  539.     pop    bx
  540.     pop    cx
  541.     pop    dx
  542. ;
  543.     call    wait_dos_free
  544. ;
  545.     or    ah,ah            ; terminate ?
  546.     je    fg_terminate        ; special treatment required
  547.     cmp    ah,4ch
  548.     je    fg_terminate        ; special treatment required
  549.     pop     ds
  550.     pop    es
  551.     popf
  552.     pop    bp
  553. ;
  554.     dos                ; execute function
  555. ;
  556. ;    Now we have to release the resources.
  557. ;
  558.     pushf                ; save registers again
  559.     sti
  560.     push    es
  561.     push    ds
  562.     push    dx
  563.     push    cx
  564.     push    bx
  565.     push    ax
  566.     push    si
  567.     push    di
  568. ;
  569.     mov    bx,SEG dgroup
  570.     mov    ds,bx
  571.     mov    es,bx
  572. ;
  573.         mov     bx,offset _upper_dos
  574.     push    ds        ; resource address
  575.     push    bx
  576.         call    _asm_release_resource
  577.     add    sp,4
  578. ;
  579.         mov     bx,offset _lower_dos
  580.     push    ds        ; resource address
  581.     push    bx
  582.         call    _asm_release_resource
  583.     add    sp,4
  584. ;
  585. ;    If both resources are free now, clear the ctask_active flag to
  586. ;    allow other background processes to gain access to DOS.
  587. ;
  588.     cli
  589.         mov     ax,_upper_dos.rstate
  590.         or    ax,ax
  591.         jz    no_relc
  592.         cmp     ax,_lower_dos.rstate
  593.     jne    no_relc
  594.     mov    cs:ctask_active,0
  595. no_relc:
  596. ;
  597. ;    All done, restore registers and return.
  598. ;
  599.     pop    di
  600.     pop    si
  601.     pop    ax
  602.     pop    bx
  603.     pop    cx
  604.     pop    dx
  605.     pop     ds
  606.     pop    es
  607.     popf
  608. ;
  609.     ret    2            ; don't restore flags
  610. ;
  611. ;
  612. ;    The terminate request requires special treatment.
  613. ;    Since terminating the program without first un-installing
  614. ;    would crash the system, we do this here, not without telling
  615. ;    the user something went very wrong.
  616. ;
  617. fg_terminate:
  618.     cli
  619.     call    _asm_remove_tasker
  620.     mov    dx,offset term_err_msg
  621.     mov    ah,9
  622.     int    21h
  623.     mov    ax,4cffh
  624.     int    21h
  625. ;
  626. ;--------------------------------------------------------------------------
  627. ;
  628. ;    Functions 0D and above
  629. ;
  630. upper_funcs:
  631.         mov     bx,offset _upper_dos
  632.     xor    cx,cx
  633.     push    cx        ; no timeout
  634.     push    cx
  635.     push    ds        ; resource address
  636.     push    bx
  637.         call    _asm_request_resource
  638.     add    sp,8
  639. ;
  640. ;    resource gained, now we may execute the function if dos is free
  641. ;
  642.     pop    di
  643.     pop    si
  644.     pop    ax
  645.     pop    bx
  646.     pop    cx
  647.     pop    dx
  648. ;
  649.     call    wait_dos_free
  650. ;
  651.     pop     ds
  652.     pop    es
  653. ;
  654. ;
  655. ;    Filter pseudo-functions C0/C1 (Absolute Read/Write)
  656. ;
  657.     cmp    ah,0c0h
  658.     jne    uf_exec1
  659.     popf
  660.     pop    bp
  661.     call    exec_absread
  662.     jmp    short uf_complete
  663. uf_exec1:
  664.     cmp    ah,0c1h
  665.     jne    uf_exec2
  666.     popf
  667.     pop    bp
  668.     call    exec_abswrite
  669.     jmp    short uf_complete
  670. ;
  671. uf_exec2:
  672.     popf
  673.     pop    bp
  674.     dos                ; execute function
  675. ;
  676. ;    Now we have to release the resources.
  677. ;
  678. uf_complete:
  679.     pushf                ; save registers again
  680.     sti
  681.     push    es
  682.     push    ds
  683.     push    dx
  684.     push    cx
  685.     push    bx
  686.     push    ax
  687.     push    si
  688.     push    di
  689. ;
  690.     mov    bx,SEG dgroup
  691.     mov    ds,bx
  692.     mov    es,bx
  693. ;
  694.         mov     bx,offset _upper_dos
  695.     push    ds        ; resource address
  696.     push    bx
  697.         call    _asm_release_resource
  698.     add    sp,4
  699. ;
  700. ;    If both resources are free now, clear the ctask_active flag to
  701. ;    allow other background processes to gain access to DOS.
  702. ;
  703.     cli
  704.         mov     ax,_upper_dos.rstate
  705.         or    ax,ax
  706.         jz    no_relc1
  707.         cmp     ax,_lower_dos.rstate
  708.     jne    no_relc1
  709.     mov    cs:ctask_active,0
  710. no_relc1:
  711. ;
  712. ;    All done, restore registers and return.
  713. ;
  714.     pop    di
  715.     pop    si
  716.     pop    ax
  717.     pop    bx
  718.     pop    cx
  719.     pop    dx
  720.     pop     ds
  721.     pop    es
  722.     popf
  723. ;
  724.     ret    2            ; don't restore flags
  725. ;
  726. ;
  727. dosentry    endp
  728. ;
  729. ;--------------------------------------------------------------------------
  730. ;
  731. ;    Absolute Read/Absolute Write.
  732. ;
  733. exec_absread    proc    near
  734.  
  735.     pushf
  736.     call    cs:savabsread
  737.     inc    sp            ; Remove flags (not using ADD,
  738.     inc    sp            ; this would clobber Carry)
  739.     ret
  740.  
  741. exec_absread    endp
  742. ;
  743. exec_abswrite    proc    near
  744.  
  745.     pushf
  746.     call    cs:savabswrite
  747.     inc    sp            ; Remove flags (not using ADD,
  748.     inc    sp            ; this would clobber Carry)
  749.     ret
  750.  
  751. exec_abswrite    endp
  752. ;
  753. ;----------------------------------------------------------------------------
  754. ;
  755. wait_dos_free    proc    near
  756. ;
  757.     push    es
  758.     push    bx
  759. in_use_loop:
  760.     cmp    idle_active,0        ; idle interrupt active?
  761.     jne    dos_free        ; then don't check for flag
  762. ;
  763.     les    bx,in_use
  764.     cmp    byte ptr es:[bx],0
  765.     jne    is_in_use
  766.     cmp    dos310,0
  767.     je    dos_free
  768.     les    bx,in_error
  769.     cmp    byte ptr es:[bx],0
  770.     je    dos_free
  771. is_in_use:
  772.     pushf
  773.     call    scheduler
  774.     jmp    in_use_loop
  775. ;
  776. dos_free:
  777.     pop    bx
  778.     pop    es
  779.     ret
  780. ;
  781. wait_dos_free    endp
  782. ;
  783. ;----------------------------------------------------------------------------
  784. ;
  785. ;    INT 28: DOS Idle Interrupt
  786. ;
  787. idleentry    proc    far
  788. ;
  789.     push    ds
  790.     push    es
  791.     push    ax
  792. ;
  793.     mov    ax,SEG dgroup
  794.     mov    ds,ax
  795.     mov    es,ax
  796. ;
  797. ;    Check if someone is waiting for upper_dos. If not, we can return
  798. ;    immediately.
  799. ;
  800.         mov     ax,word ptr _upper_dos.rwaiting
  801.         or      ax,word ptr _upper_dos.rwaiting+2
  802.     jz    idle_exit
  803. ;
  804. ;    Also make sure this is not a second invocation of INT 28.
  805. ;    Normally, this should never happen, but better safe than sorry.
  806. ;
  807.     cmp    idle_active,0
  808.     jne    idle_exit
  809.     inc    idle_active
  810. ;
  811. ;    someone is waiting, let's please him by releasing the resource
  812. ;
  813.     mov    idle_ss,ss        ; Switch to local stack
  814.     mov    idle_sp,sp
  815.     mov    ax,ds
  816.     mov    ss,ax
  817.     mov    sp,offset local_stack
  818. ;
  819.     sti                ; Interrupts allowed now
  820. ;
  821.         push    bx            ; save remaining regs
  822.     push    cx
  823.     push    dx
  824. ;
  825. ;    temporarily increase priority
  826. ;
  827.     les    bx,_tsk_current
  828.     push    es:prior[bx]
  829.     mov    es:prior[bx],0ffffh
  830.     push    bx
  831.     push    es
  832. ;
  833. ;    release resource & request it again
  834. ;
  835.     mov    ax,ds
  836.     mov    es,ax
  837.         mov     bx,offset _upper_dos
  838.     push    ds
  839.     push    bx
  840.         call    _asm_release_resource
  841.     add    sp,4
  842. ;
  843.         mov     bx,offset _upper_dos
  844.     xor    cx,cx
  845.     push    cx
  846.     push    cx
  847.     push    ds
  848.     push    bx
  849.         call    _asm_request_resource
  850.     add    sp,8
  851. ;
  852. ;    ready, restore priority, stack & regs
  853. ;
  854.     cli
  855.     pop    es
  856.     pop    bx
  857.     pop    es:prior[bx]
  858. ;
  859.     pop    dx
  860.     pop    cx
  861.     pop    bx
  862. ;
  863.     mov    ss,idle_ss        ; restore stack
  864.     mov    sp,idle_sp
  865. ;
  866.     mov    idle_active,0
  867. ;
  868. idle_exit:
  869.     pop    ax
  870.         pop     es
  871.     pop    ds
  872. ;
  873.     jmp    cs:savidle        ; chain to original interrupt
  874. ;
  875. idleentry    endp
  876. ;
  877. ;---------------------------------------------------------------------------
  878. ;
  879. ;    INT 2A: DOS Critical Section Interrupt.
  880. ;
  881. ;    Not documented.
  882. ;    Is used by DOS PRINT to mark Critical Regions.
  883. ;    Usage by PRINT:
  884. ;        AX = 8700 - Begin Critical Region
  885. ;                Returns:
  886. ;                Carry set if already active.
  887. ;        AX = 8701 - End Critical Region
  888. ;
  889. ;    Both these functions are handled here.
  890. ;
  891. ;    Other usage in DOS, function unknown:
  892. ;        AH = 82 (AL undefined)
  893. ;            seems to be called on DOS-Functions > 0C
  894. ;        AH = 84 (AL undefined)
  895. ;            seems to be called when DOS is idle
  896. ;
  897. ;    These functions are currently ignored.
  898. ;
  899. critsectint    proc    far
  900.  
  901.     cmp    ax,8700h    ; Enter critical region
  902.     jne    csi1
  903.     cmp    cs:critsect_active,0
  904.     stc
  905.     jnz    critsect_end
  906.     cmp    cs:ctask_active,0
  907.     stc
  908.     jnz    critsect_end
  909. ;
  910.     inc    cs:critsect_active
  911.     push    ax
  912.     push    bx
  913.     push    cx
  914.     push    dx
  915.     push    ds
  916.     push    es
  917.     mov    ax,seg dgroup
  918.     mov    ds,ax
  919.     mov    es,ax
  920.     mov    ax,word ptr _tsk_current
  921.     mov    word ptr cs:crit_task,ax
  922.     mov    ax,word ptr _tsk_current+2
  923.     mov    word ptr cs:crit_task+2,ax
  924.         mov     ax,offset _critical
  925.     push    ds
  926.     push    ax
  927.     call    _asm_set_flag
  928.     add    sp,4
  929.     pop    es
  930.     pop    ds
  931.     pop    dx
  932.     pop    cx
  933.     pop    bx
  934.     pop    ax
  935.     clc
  936. critsect_end:
  937.     ret    2
  938. ;
  939. csi1:
  940.     cmp    ax,8701h    ; Leave critical region
  941.     jne    csi2
  942.     mov    cs:critsect_active,0
  943.     push    ax
  944.     push    bx
  945.     push    cx
  946.     push    dx
  947.     push    ds
  948.     push    es
  949.     mov    ax,seg dgroup
  950.     mov    ds,ax
  951.     mov    es,ax
  952.         mov     ax,offset _critical
  953.     push    ds
  954.     push    ax
  955.         call    _asm_clear_flag
  956.     add    sp,4
  957.     pop    es
  958.     pop    ds
  959.     pop    dx
  960.     pop    cx
  961.     pop    bx
  962.     pop    ax
  963. csi2:
  964.     iret
  965. ;
  966. critsectint    endp
  967. ;
  968. ;
  969. ;---------------------------------------------------------------------------
  970. ;
  971.         end
  972.  
  973.